`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    12:22:30 04/05/2011 
// Design Name: 
// Module Name:    ALU 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module ALU(a, b, ALUOp, ALUresult, zero, sign);
    input [15:0] a;
    input [15:0] b;
    input [3:0] ALUOp;
    output [15:0] ALUresult;
    output zero;
    output sign;

	reg [15:0] ALUresult;
	reg zero;
	reg sign;
	always @ (a or b or ALUOp)
	begin
		casex (ALUOp)
			4'b1xxx: ALUresult <= a + b; //add
			4'b0001: ALUresult <= a - b; //sub
			4'b0010: ALUresult <= a & b; //and
			4'b0011: ALUresult <= a | b; //or
			4'b0100: ALUresult <= ~(a | b); //nor
			4'b0101: ALUresult <= a << b; //shift left
			4'b0110: ALUresult <= a >> b; //shift right
			4'b0111: begin
						if((a-b) < 0) ALUresult <= 16'h0001;
						else ALUresult <= 16'h0000;
						end
			4'b0000: begin
						if((b-a) < 0) ALUresult <= 16'h0001;
						else ALUresult <= 16'h0000;
						end
			default: $display("Error in ALU");
		endcase

	end
	
	always @ (ALUresult)
	begin
		if (ALUresult == 0) zero <= 1;
		else zero <= 0;
		
		sign <= ALUresult[15];
	end
endmodule
